module top (
    input sys_clk,
    input [4:1] key,
	input [4:1] sw,
    input uart_rx,//串口接收数据
    output uart_tx,//串口发送数据
	output [7:0] seg_sel,
	output [7:0] seg_led
);
wire rst_n;
wire locked;
wire clk;
clk_wiz_0 clk_wiz_0_inst
   (
    // Clock out ports
    .clk_out1(clk),     // output clk_out1
    // Status and control signals
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1(sys_clk)      // input clk_in1
);
assign rst_n = locked&sw[4]; // sw[4] is the reset switch
wire [15:0] acc_data;
wire [15:0] mbr_data;
wire [15:0] ax_data;
wire [15:0] bx_data;
wire [15:0] cx_data;
wire [15:0] dx_data;
wire [7:0] sp_data;
wire [15:0] br_data;
wire [15:0] mr_data;
wire [7:0] mar_data;
wire [7:0] pc_data;
wire [15:0] ir_data;

// 分频器实现：50MHz -> 5Hz
// 分频系数计算：
parameter MAX_COUNT = 25'd999;  // 5,000,000 - 1
reg [24:0] counter;                    // 25位计数器
reg cpu_clk;
always @(posedge clk or negedge locked) begin
    if (!locked) begin                  // 复位时初始化
        counter <= 0;
        cpu_clk <= 1'b0;
    end 
    else begin
        if (counter == MAX_COUNT) begin // 达到半周期计数值
            counter <= 0;             // 计数器清零
            cpu_clk <= ~cpu_clk;       // 翻转输出时钟
        end 
        else begin
            counter <= counter + 1;    // 计数器递增
        end
    end
end

//单步运行信号按键消抖
wire step;
key_filter #(
    .CNT_MAX(24'd3999_999) // Set the counter max value for debounce
) key_filter_inst (
    .sys_clk(clk),        // Connect system clock
    .sys_rst_n(locked),   // Connect reset signal
    .key_in(key[1]),      // Connect key input 
    .key_flag(step)           // Output key_flag (not connected here, add if needed)
);
//下载模式
// UART receive module instantiation
wire [7:0] fifo_din;
wire fifo_write_en;
uart_rx_byte #(
    .UART_BPS('d9600),       // UART baud rate
    .CLK_FREQ('d200_000_000)  // Clock frequency
) uart_rx_byte_inst (
    .sys_clk(clk),           // System clock
    .sys_rst_n(rst_n),       // Global reset
    .rx(uart_rx),             // UART receive data (connected to key[2] for example)
    .po_data(fifo_din),      // Parallel output data
    .po_flag(fifo_write_en)  // Data valid flag
);

// UART RX FIFO instantiation
wire fifo_read_en;
wire [9:0] rd_data_count;
wire [15:0] fifo_dout;
uart_rx_fifo uart_rx_fifo_inst (
    .clk(clk),               // Clock
    .srst(~rst_n),           // Synchronous reset
    .din(fifo_din),          // Data input
    .wr_en(fifo_write_en),   // Write enable
    .rd_en(fifo_read_en),    // Read enable
    .dout(fifo_dout),        // Data output
    .full(),        // FIFO full flag
    .rd_data_count(rd_data_count), // Read data count
    .empty()       // FIFO empty flag
);

// FIFO to memory interface instantiation
wire [15:0] load_datain;
wire [7:0] load_addr;
wire load_we;
fifo_2_mem fifo_2_mem_inst (
    .clk(clk),               // System clock
    .rst_n(rst_n),           // Global reset
    .fifo_dout(fifo_dout),   // FIFO data output
    .fifo_rd_data_count(rd_data_count), // FIFO read data count
    .fifo_read_en(fifo_read_en), // FIFO read enable
    .mem_addr(load_addr),    // Memory address
    .mem_data(load_datain),  // Memory data
    .mem_we(load_we)         // Memory write enable
);

//回传寄存器信息
wire [7:0] tx_fifo_din;
wire tx_fifo_write_en;

// UART RX FIFO instantiation
wire tx_fifo_read_en;
wire [7:0] tx_fifo_dout;
wire tx_fifo_empty;
wire tx_fifo_full;
fifo_tx_uart fifo_tx_uart_inst (
    .clk(clk),               // Clock
    .srst(~rst_n),           // Synchronous reset
    .din(tx_fifo_din),          // Data input
    .wr_en(tx_fifo_write_en),   // Write enable
    .rd_en(tx_fifo_read_en),    // Read enable
    .dout(tx_fifo_dout),        // Data output
    .full(tx_fifo_full),        // FIFO full flag
    .empty(tx_fifo_empty)       // FIFO empty flag
);

wire tx_ready;
wire pi_flag;
// FIFO write module instantiation
fifo_read tx_fifo_read_inst (
    .sys_clk(clk),               // System clock
    .sys_rst_n(rst_n),           // Global reset
    .pi_flag(pi_flag), // ouput FIFO read flag
    .tx_ready(tx_ready),      // UART ready signal
    .fifo_read_en(tx_fifo_read_en), // ouput FIFO read enable
    .fifo_empty(tx_fifo_empty) // FIFO empty flag
);

// UART TX module instantiation
uart_tx_byte #(
    .UART_BPS('d9600),       // UART baud rate
    .CLK_FREQ('d200_000_000)  // Clock frequency
) uart_tx_inst (
    .sys_clk(clk),
    .sys_rst_n(rst_n),
    .pi_data(tx_fifo_dout),
    .pi_flag(pi_flag),
    .tx_ready(tx_ready),
    .tx(uart_tx)
);

// UART TX FIFO instantiation
wire step_done;
reg_sender reg_tx (
    .clk(clk),
    .rst_n(rst_n),
    .step_mode(sw[3]),
    .step(step),
    .step_done(step_done), //单步完成信号
    .fifo_din(tx_fifo_din),    // 串口发送数据
    .fifo_write_en(tx_fifo_write_en),    // 触发发送信号

    .ACC(acc_data),
    .BR(br_data),
    .MR(mr_data),
    .AX(ax_data),
    .BX(bx_data),
    .CX(cx_data),
    .DX(dx_data),
    .SP(sp_data),
    .PC(pc_data),
    .fifo_full(tx_fifo_full), // FIFO 满标志

    .busy()
);

// CPU module instantiation
CPU CPU_inst (
    .clk(clk),           // CPU clock
    .rst_n(rst_n),           // Reset signal
    .step_mode(sw[3]),       // Step mode (controlled by switch 3)
    .step(step),             // Step signal
    .load_mode_en(sw[2]),    // Load mode enable (controlled by switch 2)
    .load_we(load_we),       // Load write enable
    .load_addr(load_addr),   // Load address
    .load_datain(load_datain), // Load data input
    .step_done(step_done),           // Step done signal (not used here)
    .ACC_data(acc_data),     // ACC register data
    .MBR_data(mbr_data),     // MBR register data
    .MAR_data(mar_data),     // MAR register data
    .PC_data(pc_data),       // PC register data
    .IR_data(ir_data),       // IR register data
    .AX_data(ax_data),       // AX register data
    .BX_data(bx_data),       // BX register data
    .CX_data(cx_data),       // CX register data
    .DX_data(dx_data),       // DX register data
    .SP_data(sp_data),       // SP register data
    .BR_data(br_data),       // BR register data
    .MR_data(mr_data)        // MR register data
);

// Instantiate the ILA and VIO cores for debugging
vio_0 vio_0_inst (
  .clk(clk),                // input wire clk
  .probe_in0(acc_data),    // input wire [15 : 0] probe_in0
  .probe_in1(mr_data),    // input wire [15 : 0] probe_in1
  .probe_in2(ax_data),    // input wire [15 : 0] probe_in2
  .probe_in3(bx_data),    // input wire [15 : 0] probe_in3
  .probe_in4(cx_data),    // input wire [15 : 0] probe_in4
  .probe_in5(dx_data),    // input wire [15 : 0] probe_in5
  .probe_in6(sp_data),    // input wire [15 : 0] probe_in6
  .probe_in7(br_data),    // input wire [15 : 0] probe_in7
  .probe_in8(mbr_data),    // input wire [15 : 0] probe_in8
  .probe_in9(ir_data),    // input wire [15 : 0] probe_in9
  .probe_in10(mar_data),  // input wire [7 : 0] probe_in10
  .probe_in11(pc_data),  // input wire [7 : 0] probe_in11
  .probe_in12(CPU_inst.CU_inst.CAR_addr), // input wire [6 : 0] probe_in12
  .probe_in13(CPU_inst.CU_inst.CAR_inst.load_mode_en), // input wire [0 : 0] probe_in13
  .probe_in14(tx_fifo_write_en), // input wire [0 : 0] probe_in14
    .probe_in15(tx_fifo_din) // input wire [7 : 0] probe_in15
);

ila_0 ila_inst (
    .clk(clk), // input wire clk

    .probe0(acc_data), // input wire [15:0]  probe0  
    .probe1(mbr_data), // input wire [15:0]  probe1 
    .probe2(ax_data), // input wire [15:0]  probe2 
    .probe3(bx_data), // input wire [15:0]  probe3 
    .probe4(cx_data), // input wire [15:0]  probe4 
    .probe5(dx_data), // input wire [15:0]  probe5 
    .probe6(sp_data), // input wire [15:0]  probe6 
    .probe7(mr_data), // input wire [15:0]  probe7 
    .probe8(mar_data), // input wire [7:0]  probe8 
    .probe9(pc_data), // input wire [7:0]  probe9
    .probe10(load_addr), //[7:0] probe10
    .probe11(load_datain),// input wire [15:0]  probe11
    .probe12(load_we),// input wire [0:0]  probe12
    .probe13(tx_fifo_din),// input wire [7:0]  probe13
    .probe14(tx_fifo_dout),// input wire [7:0]  probe14
    .probe15(tx_fifo_write_en),// input wire [0:0]  probe15
    .probe16(tx_fifo_read_en),// input wire [0:0]  probe16
    .probe17(pi_flag),
    .probe18(tx_ready),// input wire [0:0]  probe18
    .probe19(uart_tx)// input wire [0:0]  probe18

);


wire [3:0] hex7, hex6, hex5, hex4, hex3, hex2, hex1, hex0;
seg_mux seg_mux_inst (
    .hex7(hex7),
    .hex6(hex6),
    .hex5(hex5),
    .hex4(hex4),
    .hex3(hex3),
    .hex2(hex2),
    .hex1(hex1),
    .hex0(hex0),
    .key(key),
    .sw(sw),
    .AX_data(ax_data),
    .BX_data(bx_data),
    .CX_data(cx_data),
    .DX_data(dx_data),
    .ACC_data(acc_data),
    .MBR_data(mbr_data),
    .MR_data(mr_data), // Assuming MR_data is used for display
    .MAR_data(mar_data), // Added MAR_data connection
    .PC_data(pc_data),   // Added PC_data connection
    .IR_data(ir_data),    // Added IR_data connection
    .SP_data(sp_data) // Added SP_data connection
);

scan_hex_7seg scan_hex_7seg_inst (
    .clk(clk),
    .rst(~locked),
    .hex7(hex7),
    .hex6(hex6),
    .hex5(hex5),
    .hex4(hex4),
    .hex3(hex3),
    .hex2(hex2),
    .hex1(hex1),
    .hex0(hex0),
    .dp_in(8'hff), // Assuming no decimal points are used
    .seg_sel(seg_sel),
    .seg_led(seg_led)
);
endmodule